/**
 * njsvm  
 *
 * $Id: njsvm.js 6 2011-07-12 08:32:51Z leizongmin@gmail.com $
 * @author 老雷 <leizongmin@gmail.com>
 * @version 0.22
 * @date 2011-07-12 10:01:54
 */

// 使用方法：
// session = new njsvm.Session();
// instance = njsvm.newInstance('test.js', session);
// session.emit('start');
 
var	fs		= require('fs'),
	util	= require('util'),
	vm		= require('vm'),
	events	= require('events'),
	path	= require('path'),
	Session	= require('./session');

var njsvm = {};


/** 缓存 */
var CACHE = {};


/** 调试 */
var debug = function (x) {
	var tx = typeof x;
	if (tx == 'object' || tx == 'function') {
		console.log('[njsvm]:');
		console.log(x);
	}
	else {
		console.log('[njsvm] ' + x);
	}
}

//-----------------------------------------------------------------------------
/** 封装代码 */
njsvm.wrap = function (code) {
	return '(function (session, request, response) {\n' +
	
	// 为了保证调用其他模块时不出错,此处定义与nodejs一样的全局环境
	'var __dirname = session.dirname; \n' +
	'var __filename = session.filename; \n' +
	'var require = function (n) { return session.require(n, session.dirname, {}); } \n' +
	
	'var setTimeout = function () { return session.setTimeout.apply(this, arguments); } \n' +
	'var clearTimeout = function () { return session.clearTimeout.apply(this, arguments); } \n' +
	'var setInterval = function () { return session.setInterval.apply(this, arguments); } \n' +
	'var clearInterval = function () { return session.clearInterval.apply(this, arguments); } \n' +
	'var Buffer = session.Buffer; \n' +
	
	'var on = function (e,f) { return session.on(e, f); } \n' +
	'var end = function () { session.end(); } \n' +
	
	code +
	
	'\n session.on("end", function () { response.end(); });\n });';
}


/** 
 * 编译代码
 * 如果出错，则返回出错信息
 */
njsvm.compile = function (filename) {
	debug('compile "' + filename + '"');
	try {
		var code = fs.readFileSync(filename);
		code = njsvm.wrap(code);
		// debug(code);
		
		var script = vm.createScript(code, filename).runInNewContext();
		CACHE[filename] = {
			script: script,
			filename: filename,
			timestamp: new Date().getTime()
			}
		
		// 监控文件，如果文件被修改，则删除缓存
		fs.unwatchFile(filename);
		fs.watchFile(filename, function (curr, prev) {
			debug('removeCache ' + filename);
			delete CACHE[filename];
		});
	}
	catch (err) {
		// debug(err);
		return err.stack.toString();
	}
}

/**
 * 创建一个新实例
 */
njsvm.newInstance = function (filename, session, request, response) {
	try {
		if (filename in CACHE) {
			debug('new instance "' + filename + '"');
			var script = CACHE[filename].script;
			var instance = new script(session, request, response);
			return instance;
		}
		
		// 如果还没编译，则先编译该文件
		var err = njsvm.compile(filename);
		if (err) {
			return err;
		}
		else {
			return njsvm.newInstance(filename, session, request, response);
		}
	}
	catch (err) {
		return err.stack.toString();
	}
}




//-----------------------------------------------------------------------------
// 模块输出
exports.Session = Session.Session;
exports.newInstance = njsvm.newInstance;


// for (var i = 0; i < 100; i++) {
//-------------------
// session = new njsvm.Session();
// ret = njsvm.newInstance('test.js', session);
// debug(ret);
// session.emit('start');
// for (i in ret) {
//	debug(i + ret[i].toString());
// }
// }